package cn.tedu.ivos.audit.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.dto.AuditQuery;
import cn.tedu.ivos.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivos.audit.pojo.entity.Audit;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.ApplicationStatusEnum;
import cn.tedu.ivos.base.enums.AuditStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Slf4j
@Transactional
@Service
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    ApplicationMapper applicationMapper;

    @Override
    public void insertAudit(Application application) {
        log.debug("生成申请单对应的审批数据:application={}",application);
        //1.获取审批人id集合[106,103]
        List<Long> userIdList = application.getAuditUserIdList();
        //2.遍历审批人集合,有几个人,生成几条审批数据
        for(int i = 0; i< userIdList.size(); i++){
            Audit audit = new Audit();
            //设置本条审批单的相关数据
            //3.设置申请单id
            audit.setApplicationId(application.getId());
            //4.设置审批人id
            audit.setAuditUserId(userIdList.get(i));
            //5.设置审批次序 直属领导次序为0 上上级次序为1
            audit.setAuditSort(i);
            //6.设置审批单状态
            if(i==0){
                // 0表示第1条审批数据,对应的人是直属领导,审批状态为"待我审核"
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            }else{
                // 1表示第2条审批数据,对应的人是上上级,审批状态为"待他人审核"
                audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
            }
            //7.设置新增时间
            audit.setCreateTime(new Date());
            //8.审批数据入库
            auditMapper.insert(audit);
        }
    }

    @Override
    public List<AuditVO> selectAudit(AuditQuery auditQuery) {
        log.debug("查询审批单数据业务:auditQuery={}",auditQuery);
        //1.根据条件查出所有的审批数据
        List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
        //申请表与审批表联查可以查到大部分数据,但多个审批人数据需要再加工一下
        //2.遍历,依次取出每一个审批对象
        for(int i = 0; i< auditVOList.size(); i++){
            AuditVO auditVO = auditVOList.get(i);
            //3.调用自定义方法获取审批数据
            assignAuditUserList(auditVO);
        }
        //4.将准备好的数据返回给控制层
        return auditVOList;
    }

    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        log.debug("更新审批业务:auditSaveParam={}",auditSaveParam);
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveParam,audit);
        audit.setUpdateTime(new Date());
        //准备当前审批对应的申请单对象
        Application application = new Application();
        application.setId(audit.getApplicationId());
        application.setUpdateTime(new Date());
        //判断前端的审批操作是"通过"还是"驳回",分别针对不同的审批结果做后续处理
        if(audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())){//审批通过
            //更新当前审批单
            auditMapper.update(audit);
            /*继续查其他审批单:其他审批单与当前审批单对应的申请单是同一个 */
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //根据申请单id查询当前申请单对应的所有未审批的审批单总数(注意:当前审批单已审批通过!)
            Integer count = auditMapper.selectRestAuditCount(auditQuery);
            if(count>0){//还有未审核的数据
                //下一条审批单的次序是当前审批单的次序+1
                auditQuery.setAuditSort(audit.getAuditSort()+1);
                //查出下一条审批单对象
                List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
                //确保列表不为空,至少包含一条记录
                if(auditVOList !=null && auditVOList.size()>0){
                    AuditVO auditVO = auditVOList.get(0);
                    //创建空的审批对象,准备更新数据库数据
                    Audit audit2 = new Audit();
                    audit2.setId(auditVO.getId());
                    //设置第2条审批的状态为"待我审核"
                    audit2.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                    auditMapper.update(audit2);
                }
                //设置申请单状态为"审核中"(第一个人已审核,第二个人待我审核)
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.update(application);
            }else{//没有未审核的数据了
                //设置申请单状态为"已审核"(后续可分配车辆了)
                application.setStatus(ApplicationStatusEnum.AUDITED.getCode());
                applicationMapper.update(application);
            }
        }else if(audit.getAuditStatus().equals(AuditStatusEnum.REJECT.getCode())){//审批驳回
            auditMapper.update(audit);//更新当前审批单
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //根据申请单id查到所有的审批单
            List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
            //判断是否能查到审批单数据
            if(auditVOList!=null && auditVOList.size()>0){
                for(int i = 0;i< auditVOList.size();i++){
                    AuditVO auditVO = auditVOList.get(i);
                    //如果当前遍历到的审批单是"待他人审核",也就是还未审核,删除
                    if(AuditStatusEnum.PENDING.getCode().equals(auditVO.getAuditStatus())){
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            //设置申请单状态为"已驳回"并设置驳回原因
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.update(application);
        }
    }

    private void assignAuditUserList(AuditVO auditVO){
        List<String> auditUsernameList = new ArrayList<>();
        List<Long> auditUserIdList = new ArrayList<>();
        //查询当前审批单对应申请单下的所有审批单数据
        List<AuditVO> auditVOList =
                auditMapper.selectAuditByApplicationId(auditVO.getApplicationId());
        //依次获取每条审批数据
        for(int i = 0;i< auditVOList.size(); i++){
            Long userId = auditVOList.get(i).getAuditUserId();
            auditUserIdList.add(userId);
            UserVO user = userMapper.selectById(userId);
            auditUsernameList.add(user.getUsername());
        }
        StringJoiner stringJoiner = new StringJoiner(",");
        for (String username : auditUsernameList){
            stringJoiner.add(username);
        }
        auditVO.setAuditUserIdList(auditUserIdList);
        auditVO.setAuditUsernameList(stringJoiner.toString());
    }

}
